#include "defs.h"
#include "grtcirc.h"
#include "jeeps/gps.h"
+#include "jeeps/gpsserial.h"
#include "garmin_tables.h"
#include "garmin_fs.h"
#include "garmin_device_xml.h"
static char* deficon = NULL;
static char* category = NULL;
static char* categorybitsopt = NULL;
+static char* baudopt = NULL;
+static int baud = 0;
static int categorybits;
static int receiver_must_upper = 1;
"bitscategory", &categorybitsopt, "Bitmap of categories",
NULL, ARGTYPE_INT, "1", "65535"
},
+ {
+ "baud", &baudopt, "Speed in bits per second of serial port (baud=9600)",
+ NULL, ARGTYPE_INT, ARG_NOMINMAX },
+
ARG_TERMINATOR
};
categorybits = strtol(categorybitsopt, NULL, 0);
}
+ if (baudopt) {
+ baud = strtol(baudopt, NULL, 0);
+ switch (baud) {
+ case 9600:
+ case 19200:
+ case 38400:
+ case 57600:
+ case 115200:
+ break;
+ default:
+ fatal("Baud rate %d is not supported\n", baud);
+ }
+ }
+
if (GPS_Init(fname) < 0) {
fatal(MYNAME ":Can't init %s\n", fname);
}
portname = fname;
+ if (baud && baud != DEFAULT_BAUD) {
+ if (0 == GPS_Set_Baud_Rate(portname, baud)) {
+ gps_baud_rate = baud;
+ }
+ }
+
/*
* Grope the unit we're talking to to set setshort_length to
* 20 for the V,
static void
rw_deinit(void)
{
+ if (gps_baud_rate != DEFAULT_BAUD) {
+ if (0 == GPS_Set_Baud_Rate(portname, DEFAULT_BAUD)) {
+ gps_baud_rate = baud;
+ }
+ }
+
if (mkshort_handle) {
mkshort_del_handle(&mkshort_handle);
}
return h;
}
-static speed_t mkspeed(unsigned br)
+speed_t mkspeed(unsigned br)
{
switch (br) {
case 1200:
extern double gps_save_version;
extern char gps_save_string[GPS_ARB_LEN];
extern int gps_is_usb;
+extern int gps_baud_rate;
extern struct COMMANDDATA COMMAND_ID[2];
extern struct LINKDATA LINK_ID[3];
*/
#include "garminusb.h"
#include "gpsusbint.h"
+#include "gpsserial.h"
time_t gps_save_time;
double gps_save_lat;
**
** @return [int32] number of track entries
************************************************************************/
-int32 GPS_A300_Get(const char* port, GPS_PTrack** trk, pcb_fn cb)
+int32 GPS_A300_Get(const char* port , GPS_PTrack** trk, pcb_fn)
{
static UC data[2];
gpsdevh* fd;
**
** @return [int32] success
************************************************************************/
-int32 GPS_A800_Off(const char* port, gpsdevh** fd)
+int32 GPS_A800_Off(const char*, gpsdevh** fd)
{
static UC data[2];
GPS_PPacket tra;
**
** @return [int32] success
************************************************************************/
-int32 GPS_A1006_Send(const char* port,
+int32 GPS_A1006_Send(const char*,
GPS_PCourse* crs,
int32 n_crs,
gpsdevh* fd)
**
** @return [int32] success
************************************************************************/
-int32 GPS_A1007_Send(const char* port,
+int32 GPS_A1007_Send(const char*,
GPS_PCourse_Lap* clp,
int32 n_clp,
gpsdevh* fd)
**
** @return [int32] success
************************************************************************/
-int32 GPS_A1008_Send(const char* port,
+int32 GPS_A1008_Send(const char*,
GPS_PCourse_Point* cpt,
int32 n_cpt,
gpsdevh* fd)
}
}
}
+
+int32 GPS_Set_Baud_Rate(const char* port, int br)
+{
+
+ gpsdevh* fd;
+
+ if (!GPS_Device_On(port, &fd)) {
+ return gps_errno;
+ }
+
+ if (gps_is_usb) return -1; // this feature is serial only
+ GPS_Serial_Set_Baud_Rate(fd, br);
+
+ if (!GPS_Device_Off(fd)) {
+ return gps_errno;
+ }
+
+ return 0;
+
+}
const char* Get_Pkt_Type(US p, US d0, const char** xinfo);
void GPS_Prepare_Track_For_Device(GPS_PTrack** trk, int32* n);
+ int32 GPS_Set_Baud_Rate(const char* port, int br);
#endif
}
/*Stubs for unimplemented stuff*/
-int32 GPS_Command_Get_Workout(const char* port, void** lap, int (*cb)(int, struct GPS_SWay**))
+int32 GPS_Command_Get_Workout(const char*, void**, int (*cb)(int, struct GPS_SWay**))
{
return 0;
}
#include <stdio.h>
#include <time.h>
+int gps_baud_rate = DEFAULT_BAUD;
+
#if 0
#define GARMULATOR 1
char* rxdata[] = {
#else
+#include "../gbser_posix.h"
#include <sys/ioctl.h>
#include <sys/time.h>
#include <termios.h>
int32 GPS_Serial_Open(gpsdevh* dh, const char* port)
{
struct termios tty;
+ if (global_opts.debug_level >= 2) fprintf(stderr, "GPS Serial Open at %d\n", gps_baud_rate);
+ speed_t baud = mkspeed(gps_baud_rate);
posix_serial_data* psd = (posix_serial_data*)dh;
/*
tty.c_cflag &= ~(CSIZE);
tty.c_cflag |= (CREAD | CS8 | CLOCAL);
- cfsetospeed(&tty,B9600);
- cfsetispeed(&tty,B9600);
+ cfsetospeed(&tty,baud);
+ cfsetispeed(&tty,baud);
tty.c_lflag &= 0x0;
tty.c_iflag &= 0x0;
return 1;
}
+// Based on information by Kolesár András from
+// http://www.manualslib.com/manual/413938/Garmin-Gps-18x.html?page=32
+int32 GPS_Serial_Set_Baud_Rate(gpsdevh* fd, int br)
+{
+
+ struct termios tty;
+ static UC data[4];
+ GPS_PPacket tra;
+ GPS_PPacket rec;
+ speed_t speed;
+
+ speed = mkspeed(br);
+
+ // Turn off all requests by transmitting packet
+ GPS_Util_Put_Short(data, 0);
+ GPS_Make_Packet(&tra, 0x1c, data, 2);
+ if (!GPS_Write_Packet(fd,tra)) {
+ return gps_errno;
+ }
+ if (!GPS_Get_Ack(fd, &tra, &rec)) {
+ return gps_errno;
+ }
+
+ GPS_Util_Put_Int(data, br);
+ GPS_Make_Packet(&tra, 0x30, data, 4);
+ if (!GPS_Write_Packet(fd,tra)) {
+ return gps_errno;
+ }
+ if (!GPS_Get_Ack(fd, &tra, &rec)) {
+ return gps_errno;
+ }
+
+ // Receive IOP_BAUD_ACPT_DATA
+ if (!GPS_Packet_Read(fd, &rec)) {
+ return gps_errno;
+ }
+
+ // Acnowledge new speed
+ if (!GPS_Send_Ack(fd, &tra, &rec)) {
+ return gps_errno;
+ }
+ GPS_Device_Flush(fd);
+ GPS_Device_Wait(fd);
+
+ // Sleep for a small amount of time, about 100 milliseconds,
+ // to make sure the packet was successfully transmitted to the GPS unit.
+ gb_sleep(100000);
+
+ // Change port speed
+ posix_serial_data* psd = (posix_serial_data*)fd;
+ tty = psd->gps_ttysave;
+
+ cfsetospeed(&tty,speed);
+ cfsetispeed(&tty,speed);
+
+ if (tcsetattr(psd->fd,TCSANOW|TCSAFLUSH,&tty)==-1) {
+ GPS_Serial_Error("SERIAL: tcsetattr error");
+ return 0;
+ }
+
+ GPS_Util_Put_Short(data, 0x3a);
+ GPS_Make_Packet(&tra, 0x0a, data, 2);
+ if (!GPS_Write_Packet(fd,tra)) {
+ return gps_errno;
+ }
+ if (!GPS_Get_Ack(fd, &tra, &rec)) {
+ return gps_errno;
+ }
+
+ GPS_Util_Put_Short(data, 0x3a);
+ GPS_Make_Packet(&tra, 0x0a, data, 2);
+ if (!GPS_Write_Packet(fd,tra)) {
+ return gps_errno;
+ }
+ if (!GPS_Get_Ack(fd, &tra, &rec)) {
+ return gps_errno;
+ }
+
+ if (global_opts.debug_level >= 1) fprintf(stderr, "Serial port speed set to %d\n", br);
+ return 0;
+
+}
+
#endif /* __WIN32__ */
#include "gps.h"
#define usecDELAY 180000 /* Microseconds before GPS sends A001 */
+#define DEFAULT_BAUD 9600
int32 GPS_Serial_Chars_Ready(gpsdevh* fd);
// int32 GPS_Serial_Close(int32 fd, const char *port);
int32 GPS_Serial_Write_Packet(gpsdevh* fd, GPS_PPacket& packet);
int32 GPS_Serial_Send_Ack(gpsdevh* fd, GPS_PPacket* tra, GPS_PPacket* rec);
void GPS_Serial_Error(const char* hdr, ...);
-
+ int32 GPS_Serial_Set_Baud_Rate(gpsdevh* fd, int br);
#endif
* Negative on error.
* 1 if read success - even if empty packet.
*/
-int32 GPS_Packet_Read_usb(gpsdevh* dh, GPS_PPacket* packet, int eat_bulk)
+int32 GPS_Packet_Read_usb(gpsdevh*, GPS_PPacket* packet, int eat_bulk)
{
int32 n;
int32 payload_size;
#include "gpsusbint.h"
int32
-GPS_Write_Packet_usb(gpsdevh* dh, GPS_PPacket& packet)
+GPS_Write_Packet_usb(gpsdevh*, GPS_PPacket& packet)
{
garmin_usb_packet gp;
memset(&gp, 0, sizeof(gp));
--- /dev/null
+<para>
+Sets baud rate on some Garmin serial unit to the specified baud rate. Garmin protocol uses 9600 bps by default, but there is a rarely documented feature in Garmin binary protocol for switching baud rate. Highest option is 115200.
+</para>
+
+<para>
+Download track log and waypoints 12 times faster than default:
+<userinput>
+gpsbabel -t -w -i garmin,baud=115200 -f /dev/ttyUSB0 -o gpx -F garmin-serial.gpx
+</userinput>
+</para>
+
+<para>
+At the end of the transfer, baud rate is switched to back to the default
+of 9600. If connection breaks, the unit stucks at high baud rate, a power
+cycle reverts to original state.
+</para>
+
+<para>
+This option does not affect USB transfer.
+</para>
+
+<para>
+Because this feature uses undocumented Garmin protocols, it may or may
+not work on your device. The author reported success with
+eTrex Vista, GPSMAP 76s, and GPS V, but it seems likely to be problematic
+on older units and may be more problematic for writing to the device than
+reading data from the device.
+</para>